package es.xpt.ysf.commons.business;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import es.xpt.ysf.YSFException;
import es.xpt.ysf.commons.Names;
import es.xpt.ysf.commons.business.model.Currency;
import es.xpt.ysf.commons.business.model.CurrencyExchange;
import es.xpt.ysf.jaas.YSFPrincipal;
import es.xpt.ysf.model.Item;
import es.xpt.ysf.utils.ServiceLocator;

public class CurrencyExchangeStore
{	
	private Cache cache;
	private YSFPrincipal principal;
	private BusinessSession businessSession;
	
	public CurrencyExchangeStore ( YSFPrincipal principal ) 
	{
		this.principal = principal;	
		cache = CacheManager.getInstance().getCache("enumValuesCache@" + principal.getApplication());
	}
	
	@SuppressWarnings("unchecked")
	public BigDecimal getExchange ( String src, String dst, Date d ) throws YSFException 
	{
		String key = getKey(src, dst);
		Element e = cache.get( key );
		if ( e!=null && e.getObjectValue()!=null ) {
			return getExchange((List<CurrencyExchange>)e.getObjectValue(), d, src, dst);
		}
		return getExchange(loadCache( src, dst, key), d, src, dst);
		
	}
	
	private BigDecimal getExchange(List<CurrencyExchange> result, Date d, String src, String dst) throws CurrencyExchangeException {
		for ( CurrencyExchange c: result ) {
			if ( !d.after(c.getEndDate()) && !d.before(c.getInitDate()) ) {
				return c.getExchange();
			}
		}
		throw new CurrencyExchangeException("noExist.currencyExchange",new String[]{src, dst});
	}
	
	private List<CurrencyExchange> loadCache(String src, String dst, String key )  throws YSFException
	{		
		if ( businessSession == null ) 
		{
			ServiceLocator sl = new ServiceLocator(principal, "");
			businessSession = (BusinessSession)sl.getLocal(Names.BUSINESS);
		}
		
		try {
			List<CurrencyExchange> listCurrency = businessSession.getExchangesByCurrencies(new Currency(new Item(src,null)), new Currency(new Item(dst,null)));
			for ( CurrencyExchange c: listCurrency ) {
				c.setSource(null);
				c.setTarget(null);	
			}
			
			Element e = new Element(key , listCurrency);
			cache.put(e);
			return listCurrency;
		} catch ( CurrencyExchangeException e ) {
			cache.put(new Element(key , new BigDecimal(0)));
			throw e;
		}
	}

	public void remove (String src, String dst)
	{
		String key = getKey(src, dst);
		if ( !cache.isKeyInCache(key) ) { // para forzar propagar el evento
			cache.put(new Element(key, new BigDecimal(0)));
		}
		cache.remove(key);
		
	}
	
	private String getKey(String src, String dst ) {
		return src+dst + "#CURRENCY_EXCHANGE";
	}
}